【2018年版】Amazon Pinpoint で iOS のサンプルアプリ(Swift)にセグメントプッシュを送る
Amazon Pinpoint を利用したセグメントプッシュを iOS アプリに対して実施する機会がありました。諏訪が記事を書いていたのでこれ幸いと手順に沿って進めようとしたのですが… 当時からいろいろ変わっていることもあり、手間取りました。現時点でどのようにすればよいか、メモしておきます。
ちなみに私は、もともとサーバーサイドの開発を行っており、iOSを触ったのはこのタイミングが初めてでした。調べていく中で感じたのは、もともとモバイルアプリなど開発した方が AWS ないし Firebase を使ってクラウド連携する、という視点の記事はたくさんあるのですが、サーバーサイドに携わっていた人がモバイルアプリを作ってつなげてみるという状況は少ない印象です。アプリならではの証明書がらみや、プッシュ通知の概念などとても良い勉強機会になりました。
登場人物の整理
手順の話に入る前に、誰がどのような役割を担っているのか整理しておきます。
iOS アプリ
Amazon Pinpoint からプッシュ通知を受け取ります。プッシュ通知を受け取るための 証明書作成 手順があり、苦労しました。モバイルアプリサービス部のみなさんありがとうございました。
Amazon Pinpoint
以下 Pinpoint と表記します。ユーザーの行動を分析し、ユーザーに対して複数のチャネルを駆使してメッセージを送信できるサービスです。もともと、ユーザーの行動については Amazon Mobile Analytics というサービスがあったのですが、 Pinpoint に統合されました。
Pinpoint のうち、行動分析を担う部分はほぼ Mobile Analytics の機能、それに加えて セグメントの定義やキャンペーン作成、それらをもとにしたメッセージ送信(プッシュ通知、Eメール、SMS)ができるようなイメージです。このプッシュ通知機能を使って、iOS アプリに通知してみます。
AWS Mobile Hub (AWS Mobile)
この記事では以下 Mobile Hub で表記します。 Mobile Hub は、モバイルアプリケーションと AWS サービスを統合するためのサービスです。モバイルアプリ開発者の立場からみたとき、実現したいユースケースに対して、AWSのサービスをどう使い、どう構築するかというのを考えるのは、かなり骨が折れる作業です。Mobile Hub を使うことで、「ユーザーのストレージを追加したい」「認証機能を追加したい」といった具合にAWSサービスを立ち上げられます。
最近だと Amplify Framework というCLIツールを使って Mobile Hub を制御するのが推されているようですが、ここで新しいCLIツールを出すと私がさらに混乱するので、今回は画面上での操作とさせてください。
Mobile Hub を使うことで、
- ユースケースに応じて簡単にAWSサービスを立ち上げられる
- モバイルアプリで利用する設定情報をダウンロードできる
といったことができます。
ここまでの話をまとめて、これから作業していく手順は以下のようになります。
- iOS のサンプルアプリケーションを起動する
- Mobile Hub を使って Pinpoint を作成する
- iOS Pinpoint にエンドポイントを登録する
- iOS の本番用証明書を作成し、Pinpoint からプッシュ通知が送れるようにする
- Pinpoint で セグメントとキャンペーンを作成し、プッシュ通知を送る
バージョン情報
- macOS mojave 10.14.2
- Xcode 10.1
iOS のサンプルアプリケーションを起動する
現時点では、以下のドキュメントが一番良いと思います。
このチュートリアルによると、サンプルはGitHubにあるみたいですね。
私は fork して、clone しました。この後ですが、GitHub にもチュートリアルがあり、どちらに沿うか迷いますね…。もともとAWSドキュメントから始まったのでドキュメントの方に従うこととします。
clone したディレクトリに移動し、Xcode を開きます。
open MyNotes.Xcodeproj/
Xcode を開いたら、適当なシミュレータを指定して起動してみます。
ノート一覧が出現すれば成功です。ビルド時、Swift4.2にあげないかと警告されますが無視します。
Mobile Hub を使って Pinpoint を作成する
われわれは直接 Pinpoint を作成しません。Mobile Hub に作成してもらいます。いろいろ理由はあるのですが、一番はプッシュ通知証明書を設定するのが Mobile Hub 側だからです。
Create Project
Mobile Hub の画面にアクセスして新しいプロジェクトを作成します。
ここで早速注意です。可能な限り東京リージョンでリソースを作成する よう編集します。小さくて見逃しがちです。Pinpoint は東京リージョンに対応していないのでバージニアリージョンに作成されますが、認証やストレージ機能を追加していくこと考慮して、Cognito Identity Pool, S3 バケットといったリソースが東京リージョンへ作成されるようにします。
Select app platform
iOS を選択します。
Set up your backend, Connect your backend
後からでも対応できるのでスキップします。Next、Doneとして新しいプロジェクトの作成を完了してください。この手順が終わると Pinpoint が自動で作成されています。
iOS Pinpoint にエンドポイントを登録する
次は iOS アプリと Pinpoint とをつないでみましょう。まだプッシュ通知を送る段階ではありません。さきほど Mobile Hub で作成した Pinpoint の画面にアクセスします。 バージニア北部リージョン に作成されていることを注意してください。
ここから、iOSのノートアプリにPinpoint のライブラリを追加し、接続先を指定して Pinpoint とつないでいきます。
設定ファイルをプロジェクトに配置する
まず、Mobile Hub から設定ファイルをダウンロードしましょう。Moble Hub のトップページで Integrate > Donwnload Cloud Config とします。
ダウンロードした awsconfiguration.json
を、 Info.plist
と同じディレクトリに Xcode 上でコピーします。
このように設定してコピーします。これで、AWS SDK が接続先情報を利用する準備ができました。
Pinpoint のライブラリを追加する
Pinpoint のSDK を導入します。プロジェクトルートにて作業を行います。
pod init
その後、Podfileを編集して、Pinpointを追加します。
# Uncomment the next line to define a global platform for your project platform :ios, '9.0' target 'MyNotes' do # Comment the next line if you're not using Swift and don't want to use dynamic frameworks use_frameworks! # Pods for MyNotes # Analytics dependency pod 'AWSPinpoint' end
pod install --repo-update
一度 Xcode を閉じ、再度開きます。
open MyNotes.xcworkspace/
iOSコードで Pinpoint との接続を有効にする
ここなんですが…残念ながら落としてきたコードと ドキュメント記載のコードに差異があります。私が取得したサンプルコードは AnalyticsService
という抽象化されたサービスを利用しており、これをもともとの LocalAnalyticsService
から実際にAWSと接続する AWSAnalyticsService
を作成します。実はこのクラスは GitHub の手順のほうには記載があります。このあたり本当に混乱しました…。
Create Analytics Service Class
Xcode で、MyNotes グループにおいて New File > Swift File > AWSAnalyticsService として Swift ファイルを作成します。GitHubの記載に従い以下のようにします。
import Foundation import AWSCore import AWSPinpoint class AWSAnalyticsService : AnalyticsService { var pinpoint: AWSPinpoint? init() { let config = AWSPinpointConfiguration.defaultPinpointConfiguration(launchOptions: nil) pinpoint = AWSPinpoint(configuration: config) } func recordEvent(_ eventName: String, parameters: [String : String]?, metrics: [String : Double]?) { let event = pinpoint?.analyticsClient.createEvent(withEventType: eventName) if (parameters != nil) { for (key, value) in parameters! { event?.addAttribute(value, forKey: key) } } if (metrics != nil) { for (key, value) in metrics! { event?.addMetric(NSNumber(value: value), forKey: key) } } pinpoint?.analyticsClient.record(event!) pinpoint?.analyticsClient.submitEvents() } }
さらに、AppDelegate.swift
で定義している AnalyticsService
のインスタンスはモックサービスになっているので、これを上で定義したものに差し替えます。
// Initialize the analytics service // analyticsService = LocalAnalyticsService() analyticsService = AWSAnalyticsService()
以上で修正は終わりです。シミュレータを起動します。いくつかメモ帳を操作をした後、Pinpoint のコンソールを開きます。
新しいエンドポイントとしてひとつでも認識されていればOKです。
iOS の本番用証明書を作成し、Pinpoint からプッシュ通知が送れるようにする
ノートアプリと Pinpoint が接続できたことを確認できました。プッシュ通知を送るわけですが、注意点があります。
- Pinpoint のセグメントプッシュには 本番用 プッシュ通知証明書が必要
- ワイルドカードアプリIDは利用不可。プッシュ通知が届きません
- 本番用の プロビジョニングプロファイルが必要となり、Apple Developer Program への登録が必要
- CertificateSigningRequest を作成する際、署名は 半角英数字が良い
- プッシュ通知証明書のP12を生成する際、パスワードを設定する
アプリ開発に慣れていたらすぐにわかるのかもしれませんが、ここでかなり時間を使ってしまいました。さらに、ここからは Mobile Hub のチュートリアルはありません。Pinpoint のチュートリアルになります。
この手順に従って証明書を作成してください。手元のマシンは以下のような状態になるはずです。
- 本番用の APN プッシュ通知証明書が、キーチェーンにインストールされている
- 本番用の APN プッシュ通知証明書 P12ファイルが生成されている(パスワード付!)
- iOS ディストリビューション証明書が、キーチェーンにインストールされている
- 本番用プロビジョニングプロファイルが Xcode にインストールされている
ここまで行った後、 Xcode での作業に移ります。
Bundle Identifier を修正する
App Id で指定したものに修正します。Buld Settings > Targets(MyNotes) > General で、 Bundle Identifierを修正します。
さらにこの状態で 画面下にある 「Automatically Manage sigining」を有効にします。上記、証明書の準備が正しく行われれていれば、エラーにはならないはずです。
ノートアプリの プッシュ 通知を有効にする
同じく Buld Settings > Targets(MyNotes) で、こんどは Capabilities タブを選びます。Push Notification があるのでそれを有効にします。
ユーザーに通知の許可を求め、デバイストークンを Pinpoint に送信する実装を追加
AppDelegate の applicaiton に以下の処理を追加します。
// Push notifications let center = UNUserNotificationCenter.current() center.requestAuthorization(options: [.alert, .badge, .sound], completionHandler: { (granted, error) in if granted { print("Allowed") application.registerForRemoteNotifications() } else { print("Didn't allowed") } })
さらに、Pinpoint がプッシュ通知を送れるよう、デバイストークンを送信します。まず、AnalyticsServce, AWSAnalyticsServce にデバイストークンを送信する処理を追加します。
import Foundation protocol AnalyticsService { func recordEvent(_ eventName: String, parameters: [String:String]?, metrics: [String:Double]?) -> Void func registerDevice(_ deviceToken: Data) }
func registerDevice(_ deviceToken: Data) { pinpoint?.notificationManager.interceptDidRegisterForRemoteNotifications(withDeviceToken: deviceToken) let token = deviceToken.map { String(format: "%.2hhx", $0) }.joined() print("deviceToken: \(token)") }
これを、AppDelegate から使います。
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { analyticsService?.registerDevice(deviceToken) }
ビルドして実機へインストールする
Pinpoint は本番プッシュ証明書を利用する関係上、プロビジョニングプロファイルも本番用でなくてはいけません。まず、ターゲットのスキーマが、App ID 作成時に指定したiOSの実機になっていることを確認してください。
その後、Xcode 上部メニュー Product > Archive としてアーカイブを作ります。Archivesウィンドウで、 Distribute App とします。distribution method は、Ad hoc です。
オプション設定は特に何もせずにNext、re-sign の設定では Automatically manage signing とします。これで、ipaファイルを含むフォルダが生成されるので、適当な場所に置きます。このipaファイルを実機へインストールします。Xcode 上部メニュー Window > Devices and Simulators と選んでください。この画面で、+
ボタンを押して先程作成したipaファイルを選択することでインストールできます。
iOS の実機で、アプリが起動することを確認してください。このとき、「プッシュ通知を許可しますか?」と聞かれるはずです。
「許可」します。これでアプリ側は準備OKです。
Mobile Hub に 本番プッシュ証明書のP12ファイルを登録する
Mobile Hub でプッシュ通知の設定を行います。AWSマネジメントコンソール、Mobile Hub の test-note
トップ画面で Messaging and Analytics
を選択してください。
その後、Messaging > Mobile push > iOS とクリックしていきます。P12ファイルを選ぶUIになると思うので、パスワードを設定した P12ファイルを選択、パスワードを入力してアップロードします。その後、画面下部Enable
ボタンをおします。
これでプッシュ通知を行う準備ができました。
Pinpoint で セグメントとキャンペーンを作成し、プッシュ通知を送る
それではプッシュ通知を送ります。Pinpoint では、「セグメント」と「キャンペーン」を作って、セグメントプッシュを送っていきます。
セグメントを作る
Pinpoint のtestnote
画面で、左メニュー Segments
から新しいセグメントを作成してください。名前は何でもOKです。Segment group の設定ですが、本来はここでユーザーの属性だったり、モバイルOSの種類でセグメント対象を絞ることができます。今回は1端末しか登録していないので、「メッセージチャネルがPUSH通知になっているものすべて」という設定にしてみましょう。
このとき、右側のSegment estimate
で 対象になっているエンドポイントが少なくとも1つ以上あることを確認してください。ここで対象エンドポイントがない場合、デバイストークンが正しく送信されていない可能性があります。問題ないことを確認したら、「Create Segment」としてください。これでセグメントの作成は完了です。
キャンペーンを作る
キャンペーンとは、メッセージ送信計画のようなものです。A/Bテストを行ったり、定期的な配信の設定が行えます。プッシュ通知はキャンペーン設定のもとを送信されるため、セグメントに続きこちらも作っていきます。左メニューCampaings > Create a campaign としてください。
Create a campaign
名前は適当、Campaign type は Standard campaign でOKです。
Choose a segment
Use an exiting segment とします。Segment は、先程作成したものを指定します。
Create your message
以下のように設定します。
- Specifications: Push notifications
- Push notification details
- Notification type: Standard notification
- Message content: Create a new message
- Title: ノートアプリへのプッシュテスト
- Body: Pinpointのセグメントプッシュです
- Action: Open your app
Choose when to send the campaign
- At a specific time
- Immediately
とします。発射します。
頼む…!
無事届きました!
まとめ
なにもないところからスタートすると、ずいぶんと長い道のりに感じました。Mobile Hub によって、モバイルアプリからAWSを使うハードルが大幅に下がり、一人のエンジニアでもアプリ・サーバを一緒に組み上げられるようになりました。モバイルアプリとPinpointを使うなら、「じゃあプッシュ通知も」となるのは自然な流れだと思います。この記事は、自分自身のために書いたところが大きく、今後、ふたたびプッシュ通知をPinpointで行うことになった場合に読み返そうと思います。どなたかの参考になれば幸いです。
今回は、Pinpoint のセグメントはほとんど形だけ、1デバイスに対して送るというものでした。Pinpointはまだまだいろいろなことができると思います。連携できることがわかった以上、機能を調べて、どのようなプッシュ通知が送れるか、今後試していくのが楽しみです。